package com.koron.util;

import com.koron.css2.ServerInterface;
import com.koron.css2.baseConfig.mapper.ValidataRepeatMapper;
import com.koron.css2.serviceManage.bean.RequestBean;
import com.koron.css2.serviceManage.bean.UserInfoBean;
import com.koron.css2.serviceManage.utils.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.ADOConnection;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.SqlTask;
import org.swan.bean.MessageBean;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CheckFieldUtils {
	
	public static MessageBean<?> checkField(ServerInterface serverInterface, Object data, String dbEnv) throws Exception {
		Class<?> clazz =  serverInterface.getClass();
		Method method = clazz.getMethod("exec", new Class[] {SessionFactory.class, UserInfoBean.class, RequestBean.class});
		ValidationKey validationKey = method.getAnnotation(ValidationKey.class);
		Parameter[] parameters = method.getParameters();
		Parameter parameter = parameters[2];
		if(validationKey == null) {
			validationKey = parameter.getAnnotation(ValidationKey.class);
		}
		if(validationKey == null) {
			return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "校验成功", Void.class);
		}
		Class<?> validataClazz = validationKey.clazz();
		String group = validationKey.method();
		Class<?> paramClazz = data.getClass();
		if(paramClazz.getTypeName().equals("java.util.ArrayList")) {
			List<?> list = JsonUtils.objectToList(data, validataClazz);
			for(Object o : list) {
				MessageBean<?> result = validata(validataClazz, o, group, dbEnv);
				if(result.getCode() != Constant.MESSAGE_INT_SUCCESS) {
					return result;
				}
			}
		}
		if(paramClazz.getTypeName().equals("java.util.LinkedHashMap")) {
			Object o = JsonUtils.objectToPojo(data, validataClazz);
			Field[] fields = validataClazz.getDeclaredFields();
			for(Field field : fields) {
				o=JsonUtils.objectToPojo(data, validataClazz);
				ValidationKey vkey = field.getAnnotation(ValidationKey.class);
				if(vkey != null) {
					Class<?> fieldClass = field.getType();
					if(fieldClass.getName().equals("java.util.List")) {
						List<?> list = (List<?>) GenericUtils.getValue(field, o);
						if(list != null) {
							for(Object oo : list) {
								MessageBean<?> result = validata(vkey.clazz(), oo, group, dbEnv);
								if(result.getCode() != Constant.MESSAGE_INT_SUCCESS) {
									return result;
								}
							}
						}
					}
					//vkey.getClass().getName();
					if(vkey.clazz().getName().equals(fieldClass.getName())) {
						o = GenericUtils.getValue(field, o);
						if(o != null) {
							MessageBean<?> result = validata(vkey.clazz(), o, group, dbEnv);
							if(result.getCode() != Constant.MESSAGE_INT_SUCCESS) {
								return result;
							}
						}
					}
				}
			}
			MessageBean<?> result = validata(validataClazz, o, group, dbEnv);
			if(result.getCode() != Constant.MESSAGE_INT_SUCCESS) {
				return result;
			}
		}
		return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "校验成功", Void.class);
	}
	
	private static MessageBean<?> validata(Class<?> clzz, Object o, String method, String dbEnv) throws Exception {
		Field[] fields = clzz.getDeclaredFields();
		for(Field field : fields) {
			//新增过滤掉静态变量验证
			boolean isStatic = Modifier.isStatic(field.getModifiers());
			if(isStatic) {
				continue;
			}
			Object value = GenericUtils.getValue(field, o);
			Check check = field.getAnnotation(Check.class);
			if(check == null) {
				continue;
			}
			if(check.notNull() && value == null) {
				return errorMessage(check.name() + "不能为空");
			}
			if(check.notEmpty() && field.getType().getName().equals("java.lang.String")) {
				if(value == null || StringUtils.isEmpty(value.toString())) {
					return errorMessage(check.name() + "不能为空");
				}
				if(check.min() > 0 && value.toString().length() < check.min()) {
					return errorMessage(check.name() + "长度不能小于" + check.min());
				}
				if(check.max() > 0 && value.toString().length() > check.max()) {
					return errorMessage(check.name() + "长度不能大于" + check.max());
				}
			}
			if(value != null && check.number()) {
				boolean p = Pattern.matches("-?[0-9]+.?[0-9]*", value.toString());
				if(!p) {
					return errorMessage(check.name() + "必须为数字类型");
				}
				double d = Double.parseDouble(value.toString());
				if(check.min() >= 0 && d < check.min()) {
					return errorMessage(check.name() + "不能小于" + check.min());
				}
				if(check.max() >= 0 && d > check.max()) {
					return errorMessage(check.name() + "不能大于" + check.max());
				}
			}
			if(value != null && check.code()) {
				Pattern p = Pattern.compile("[\u4e00-\u9fa5]+");
		        Matcher matcher = p.matcher(value.toString());
		        if(matcher.find()) {
		        	return errorMessage(check.name() + "不能包含中文");
		        }
			}
			String pattern = check.pattern();
			if(value != null && StringUtils.isNotEmpty(pattern)) {
				boolean p = Pattern.matches(pattern, value.toString().trim());
				if(!p) {
					return errorMessage(check.name() + "不符合规范");
				}
			}
			com.koron.util.Check.Repeat[] repeats = check.repeat();
			if(value != null && repeats.length > 0 && "insert".equalsIgnoreCase(method)) {
				com.koron.util.Check.Repeat repeat = repeats[0];
				String tableName = repeat.tableName();
				String columnName = repeat.columnName();
				String fieldName = repeat.fieldName();
				if(StringUtils.isEmpty(fieldName)) {
					fieldName = field.getName();
				}
				if(StringUtils.isEmpty(columnName)) {
					columnName = getCloumnName(fieldName);
				}
				String dataType = getDataType(tableName, columnName, dbEnv);
				if(StringUtils.isNotBlank(dataType)) {
					if(field.getType().getName().equals("java.util.Date") && "date".equals(dataType)) {
						value = DateUtils.parseDate((Date)value, "yyyy-MM-dd");
					}
					if(field.getType().getName().equals("java.util.Date") && "datetime".equals(dataType)) {
						value = DateUtils.parseDate((Date)value, "yyyy-MM-dd HH:mm:ss");
					}
					int iCount = validataRepeat(tableName, columnName, value.toString(), dbEnv);
					if(iCount > 0) {
						return errorMessage(check.name() + "字段的值已存在");
					}
				}
			}
		}
		return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "校验成功!", Void.class);
	}
	
	private static int validataRepeat(String tableName, String columnName, String o, String dbEnv){
		return ADOConnection.runTask(dbEnv, new SqlTask() {
			@Override
			public Object run(SessionFactory factory) {
				ValidataRepeatMapper mapper = factory.getMapper(ValidataRepeatMapper.class);
				return mapper.validataRepeat(tableName, columnName, o.toString());
			}
		}, Integer.class);
	}
	
	private static String getDataType(String tableName, String columnName, String dbEnv){
		return ADOConnection.runTask(dbEnv, new SqlTask() {
			@Override
			public Object run(SessionFactory factory) {
				ValidataRepeatMapper mapper = factory.getMapper(ValidataRepeatMapper.class);
				return mapper.getDataType(tableName, columnName);
			}
		}, String.class);
	}
	
	private static MessageBean<?> errorMessage(String message){
		return MessageBean.create(Constant.MESSAGE_DBFAIL, message, Void.class);
	}
	
	private static String getCloumnName(String fieldName) {
		char[] chars = fieldName.toCharArray();
		StringBuilder strBuil = new StringBuilder();
		for(int i = 0; i < chars.length; i++) {
			char c = chars[i];
			if(Character.isUpperCase(c) && strBuil.length() > 0) {
				strBuil.append("_");
			}
			strBuil.append(Character.toLowerCase(c));
		}
		return strBuil.toString();
	}
	
	public static void main(String[] args) {
		boolean p = Pattern.matches("-?[0-9]+.?[0-9]*", "0");
		System.out.println(p);
	}
	
}
